﻿#define  _CRT_SECURE_NO_WARNINGS 1
#include<iostream>

using namespace std;


////0-N个参数
//template <class ...Args>
//void Print(Args&&... args)
//{
//	cout << sizeof...(args) << endl;  //可以用sizeof...来算参数包中的参数个数
//}


////包扩展（解析出参数包的内容）
//void ShowList()
//{
//	// 编译器时递归的终⽌条件，参数包是0个时，直接匹配这个函数 
//	cout << endl;
//}
//template <class T, class ...Args>
//void ShowList(T&& x, Args&&... args)
//{
//	cout << x << " ";
//	// args是N个参数的参数包 
//	// 调⽤ShowList，参数包的第⼀个传给x，剩下N-1传给第⼆个参数包 
//	ShowList(args...);
//}
//
//// 编译时递归推导解析参数 
//template <class ...Args>
//void Print(Args&&... args)
//{
//	ShowList(args...);
//}





template<class T>
const T& GetArg(const T& x)
{
	cout << x << " ";
	return x;
}

//int GetArg(const T& x)
//{
//	cout << x << " ";
//	return 0;
//}


//包扩展（通过解析参数包，把参数包参数依次传给getarg（）
template<class ...Args>
void Arguments(Args... args)
{}

template<class ...Args>
void Print(Args... args)
{
	Arguments(GetArg(args)...);   //参数包有几个参数就调用几次getarg，让它的返回值组成参数包给Arguments
	cout << endl;
}

int main()
{
	double x = 2.2;
	Print(); // 包⾥有0个参数 
	Print(1); // 包⾥有1个参数 
	Print(1, string("xxxxx")); // 包⾥有2个参数 
	Print(1, 1.1);			// 包⾥有2个参数
	Print(1.1, string("xxxxx"), x); // 包⾥有3个参数 

	return 0;
}